package com.xinsoft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xinsoft.common.exception.BDException;
import com.xinsoft.constant.Const;
import com.xinsoft.entity.dto.ScmMaterialReturnApplyDTO;
import com.xinsoft.entity.dto.ScmMaterialReturnApplyParam;
import com.xinsoft.entity.po.ScmMaterialReturnApply;
import com.xinsoft.entity.po.ScmMaterialReturnApplyItem;
import com.xinsoft.entity.po.ScmMaterialReturnApply;
import com.xinsoft.entity.vo.*;
import com.xinsoft.mapper.ScmMaterialReturnApplyItemMapper;
import com.xinsoft.service.ScmMaterialReturnApplyItemService;
import com.xinsoft.service.ScmMaterialReturnApplyService;
import com.xinsoft.mapper.ScmMaterialReturnApplyMapper;
import com.xinsoft.service.SysDocumentNumService;
import com.xinsoft.utils.TokenUtil;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ZYM
 * @description 针对表【scm_material_return_apply(退料申请)】的数据库操作Service实现
 * @createDate 2023-09-26 13:27:58
 */
@Service
public class ScmMaterialReturnApplyServiceImpl extends ServiceImpl<ScmMaterialReturnApplyMapper, ScmMaterialReturnApply>
        implements ScmMaterialReturnApplyService {

    @Resource
    private ScmMaterialReturnApplyItemMapper materialReturnApplyItemMapper;

    @Autowired
    private SysDocumentNumService sysDocumentNumService;
    @Autowired
    private ScmMaterialReturnApplyItemService materialReturnApplyItemService;

    @Override
    public IPage<ScmMaterialReturnApplyPageVo> findPageListByParam(ScmMaterialReturnApplyParam param) {
        Page<ScmMaterialReturnApplyPageVo> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        IPage<ScmMaterialReturnApplyPageVo> pageList = baseMapper.findListByParam(page, param);
        return pageList;
    }

    @Override
    public List<ScmMaterialReturnApplyPageVo> findListByParam(ScmMaterialReturnApplyParam param) {
        return baseMapper.findListByParam(param);
    }

    @Override
    public Integer tempSave(ScmMaterialReturnApplyDTO dto) {
        ScmMaterialReturnApply apply = new ScmMaterialReturnApply();
        BeanUtils.copyProperties(dto, apply);
        apply.setAuditStatus(Const.AUDIT_STATUS_WAIT);
        List<ScmMaterialReturnApplyItem> itemList = dto.getScmMaterialReturnApplyItemList();
        // 保存或新增
        if (Objects.isNull(apply.getId())) {
            // 更新流水号
            sysDocumentNumService.incrementLastSerialByDocumentId(Const.DOCUMENT_ID.MATERIAL_RETURN_APPLY_DOCUMENT);
        } else {
            materialReturnApplyItemService.remove(Wrappers.lambdaQuery(ScmMaterialReturnApplyItem.class).eq(ScmMaterialReturnApplyItem::getReturnApplyId, apply.getId()));
        }

        this.saveOrUpdate(apply);
        // 保存退料申请明细
        itemList.forEach(item -> {
            item.setReturnApplyId(apply.getId());
        });
        materialReturnApplyItemService.saveBatch(itemList);

        return apply.getId();
    }

    @Override
    public ScmMaterialReturnApplyDetailVo detail(Integer id) {
        ScmMaterialReturnApplyDetailVo vo = baseMapper.getById(id);
        List<ScmMaterialReturnApplyItemVo> itemVoList = materialReturnApplyItemMapper.listByReturnApplyId(id);
        vo.setScmMaterialReturnApplyItemList(itemVoList);
        return vo;
    }

    @Override
    public void del(List<Integer> ids) {
        List<ScmMaterialReturnApply> list = this.list(Wrappers.lambdaQuery(ScmMaterialReturnApply.class)
                .eq(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_NORMAL)
                .in(ScmMaterialReturnApply::getId, ids));
        if (list.size() > 0) {
            throw new BDException("操作失败，已审核的单据不能删除");
        }
        materialReturnApplyItemService.remove(Wrappers.lambdaQuery(ScmMaterialReturnApplyItem.class).in(ScmMaterialReturnApplyItem::getReturnApplyId, ids));
        this.removeByIds(ids);
    }

    @Override
    public void audit(List<Integer> ids) {
        List<ScmMaterialReturnApply> returnApplyList = this.list(Wrappers.lambdaQuery(ScmMaterialReturnApply.class)
                .in(ScmMaterialReturnApply::getId, ids)
                .eq(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_NORMAL));
        if (CollectionUtil.isNotEmpty(returnApplyList)) {
            throw new BDException("该单据已审核，无需重复审核");
        }

        // 1.审核
        this.update(Wrappers.lambdaUpdate(ScmMaterialReturnApply.class)
                .in(ScmMaterialReturnApply::getId, ids)
                .eq(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_WAIT)
                .set(ScmMaterialReturnApply::getAuditId, TokenUtil.getUserId())
                .set(ScmMaterialReturnApply::getAuditTime, new Date())
                .set(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_NORMAL));
    }

    @Override
    public void reverseAudit(List<Integer> ids) {
        List<ScmMaterialReturnApply> returnApplyList = this.list(Wrappers.lambdaQuery(ScmMaterialReturnApply.class)
                .in(ScmMaterialReturnApply::getId, ids)
                .eq(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_WAIT));
        if (CollectionUtil.isNotEmpty(returnApplyList)) {
            throw new BDException("该单据未审核，无需反审核");
        }

        // 1.反审核
        this.update(Wrappers.lambdaUpdate(ScmMaterialReturnApply.class)
                .in(ScmMaterialReturnApply::getId, ids)
                .eq(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_NORMAL)
                .set(ScmMaterialReturnApply::getAuditId, null)
                .set(ScmMaterialReturnApply::getAuditTime, null)
                .set(ScmMaterialReturnApply::getAuditStatus, Const.AUDIT_STATUS_WAIT));
    }

    @Override
    public IPage<ScmMaterialReturnApplyVo> headList(ScmMaterialReturnApplyParam param) {
        Page<ScmMaterialReturnApplyVo> page = new Page<>(param.getCurrentPage(), param.getPageSize());
        return baseMapper.headList(page, param);
    }
}




